package com.microlearning.common.elasticsearch.utils;

import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.springframework.beans.factory.annotation.Autowired;
import com.alibaba.fastjson2.JSON;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * es相关工具类
 */
public class ElasticSearchUtils {

    @Autowired
    public RestHighLevelClient restHighLevelClient;

    /**
     * 创建索引
     */
    public void createIndex(String index) {
        // 创建request对象
        CreateIndexRequest request = new CreateIndexRequest(index);
        try {
            // 准备请求参数
            CreateIndexResponse response = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
            if (response.isAcknowledged()) {
                System.out.println("创建索引(" + index + ")成功");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭客户端
            try {
                restHighLevelClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 判断索引是否存在
     */
    public boolean isIndexExist(String index) {
        // 创建request对象
        GetIndexRequest request = new GetIndexRequest(index);
        try {
            // 准备请求参数
            return restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭客户端
            try {
                restHighLevelClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
     * 删除索引
     */
    public void deleteIndex(String index) {
        // 创建request对象
        DeleteIndexRequest request = new DeleteIndexRequest(index);
        try {
            // 准备请求参数
            AcknowledgedResponse response = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
            if (response.isAcknowledged()) {
                System.out.println("删除索引(" + index + ")成功");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭客户端
            try {
                restHighLevelClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 添加文档
     */
    public void addDocument(String index, String id, Object data) {
        // 创建请求
        IndexRequest request = new IndexRequest(index);
        // 设置文档ID
        request.id("1");
        // 设置超时时间
        request.timeout(TimeValue.timeValueMillis(1000));
        // 发起请求
        request.source(JSON.toJSONString(data), XContentType.JSON);
        try {
            IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT);
            if (response.status().getStatus() == 201) {
                System.out.println("添加文档成功");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭客户端
            try {
                restHighLevelClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取指定文档信息
     */
    public List<String> getDocument(String index, String id) {
        // 创建请求
        SearchRequest searchRequest = new SearchRequest(index);
        // 返回结果
        List<String> results = new ArrayList<>();
        try {
            SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            for (SearchHit hit : search.getHits().getHits()) {
                results.add(hit.getSourceAsString());
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭客户端
            try {
                restHighLevelClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return results;
    }

    /**
     * 判断文档是否存在
     */
    public boolean isDocumentExist(String index, String id) {
        // 创建请求
        GetRequest request = new GetRequest(index, id);
        // 请求参数
        request.fetchSourceContext(new FetchSourceContext(false));
        request.storedFields("_none_");
        try {
            // 发起请求
            return restHighLevelClient.exists(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭客户端
            try {
                restHighLevelClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
     * 更新文档
     */
    public void updateDocument(String index, String id, Object data) {
        // 创建请求
        UpdateRequest request = new UpdateRequest(index, id);
        // 请求参数
        request.doc(JSON.toJSONString(data), XContentType.JSON);
        try {
            // 发起请求
            UpdateResponse response = restHighLevelClient.update(request, RequestOptions.DEFAULT);
            if (response.status().getStatus() == 200) {
                System.out.println("更新文档成功");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭客户端
            try {
                restHighLevelClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 删除文档
     */
    public void deleteDocument(String index, String id) {
        // 创建请求
        DeleteRequest request = new DeleteRequest(index, id);
        // 请求参数
        request.timeout("1s");
        try {
            // 发起请求
            DeleteResponse response = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
            if (response.status().getStatus() == 200) {
                System.out.println("删除文档成功");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭客户端
            try {
                restHighLevelClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 批量添加文档
     *
     * @throws IOException
     */
    /*@Test
    public void testBatchAdd() throws IOException {
        BulkRequest bulkRequest = new BulkRequest();
        for (int i = 0; i < 3; i++) {
            IndexRequest request = new IndexRequest("boot_index");// 没有id会自动生成一个随机ID
            request.id(String.valueOf(i));
            request.source(JSON.toJSONString(new User("liu" + i, 15 + i)), XContentType.JSON);
            bulkRequest.add(request);
        }
        BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        System.out.println(bulkResponse.status());
        if (bulkResponse.hasFailures()) {
            // 处理批量添加失败的情况
        }
    }*/

    /**
     * 复杂查询
     * SearchRequest 搜索请求
     * SearchSourceBuilder 条件构造
     * HighlightBuilder 高亮
     * TermQueryBuilder 精确查询
     * MatchAllQueryBuilder
     * xxxQueryBuilder ...
     *
     * @throws IOException
     */
    /*@Test
    public void testSearch() throws IOException {
        // 1.创建查询请求对象
        SearchRequest searchRequest = new SearchRequest();
        // 2.构建搜索条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // (1)查询条件 使用QueryBuilders工具类创建
        // 精确查询
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "liu0");
        //        // 匹配查询
        //        MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
        // (2)其他<可有可无>：（可以参考 SearchSourceBuilder 的字段部分）
        // 设置高亮
        searchSourceBuilder.highlighter(new HighlightBuilder());
        //        // 分页
        //        searchSourceBuilder.from();
        //        searchSourceBuilder.size();
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        // (3)条件投入
        searchSourceBuilder.query(termQueryBuilder);
        // 3.添加条件到请求
        searchRequest.source(searchSourceBuilder);
        // 4.客户端查询请求
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        // 5.查看返回结果
        SearchHits hits = search.getHits();
        System.out.println(JSON.toJSONString(hits));
        System.out.println("=======================");
        for (SearchHit documentFields : hits.getHits()) {
            System.out.println(documentFields.getSourceAsMap());
        }
    }*/

}
